﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.ObjectModel;

namespace Calhoon.MarkupParser
{
	public delegate bool ExpectedPatternHandler(ParseState state, int patterns);

	public class ParseState
	{
		private int mIndex;
		public int Index {
			get {
				return mIndex;
			}
		}

		private string mSource;
		public string Source {
			get {
				return mSource;
			}
			set {
				mSource = value;
				mIndex = 0;
				mDocument = new Collection<PrimitiveTag>();
			}
		}

		private Collection<PrimitiveTag> mDocument;
		public Collection<PrimitiveTag> Document {
			get {
				return mDocument;
			}
		}

		public bool EndOfFile {
			get {
				return mIndex >= mSource.Length;
			}
		}

		public virtual bool IsWhiteSpace(char letter) {
			return " \r\n\t".Contains(letter);
		}

		public virtual void EatWhiteSpace() {
			while (!EndOfFile && IsWhiteSpace(mSource[mIndex])) {
				++mIndex;
			}
		}

		public virtual void EatUnexpected(params string[] expected) {
			while (!EndOfFile && !IsExpected(expected)) {
				++mIndex;
			}
		}

		public virtual void EatUnexpected(ExpectedPatternHandler expectedHandler, int patterns, params string[] expected) {
			while (!EndOfFile && !expectedHandler(this, patterns) && !IsExpected(expected)) {
				++mIndex;
			}
		}

		protected virtual bool IsExpected(string[] expected) {
			foreach (string exp in expected) {
				if (Peek(exp.Length) == exp) {
					return true;
				}
			}

			return false;
		}

		public string Peek(int places) {
			if (mIndex + places > mSource.Length) {
				places = mSource.Length - mIndex;
			}

			return mSource.Substring(mIndex, places);
		}

		public char Peek() {
			return mSource[mIndex];
		}

		public char Advance() {
			char ret = Peek();
			++mIndex;

			return ret;
		}

		public void Advance(int len) {
			mIndex = Math.Min(mIndex + len, mSource.Length);
		}
	}
}